/*
 * Copyright (c) 2016. For Intelligent Group.
 */
package com.intelligent.ispc.core.service.impl;

import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Lists;
import com.google.common.collect.Table;
import com.intelligent.ispc.common.mapper.BeanMapper;
import com.intelligent.ispc.common.utils.ApplicationException;
import com.intelligent.ispc.common.utils.ApplicationUtil;
import com.intelligent.ispc.common.utils.ExceptionMessages;
import com.intelligent.ispc.common.utils.StringUtils;
import com.intelligent.ispc.common.web.ProcessEvent;
import com.intelligent.ispc.core.dto.*;
import com.intelligent.ispc.core.entity.Project;
import com.intelligent.ispc.core.entity.ToleranceItem;
import com.intelligent.ispc.core.entity.ToleranceScheme;
import com.intelligent.ispc.core.repository.jpa.ProjectDao;
import com.intelligent.ispc.core.repository.jpa.StatisticAnalysisParameterDao;
import com.intelligent.ispc.core.repository.jpa.ToleranceItemDao;
import com.intelligent.ispc.core.repository.jpa.ToleranceSchemeDao;
import com.intelligent.ispc.core.service.ExportFileService;
import com.intelligent.ispc.core.service.ProjectService;
import com.intelligent.ispc.core.service.SecurityService;
import com.intelligent.ispc.core.service.ToleranceService;
import com.intelligent.ispc.export.tolerance.TolExcelBuilder;
import com.intelligent.ispc.export.tolerance.TolExportCellFactory;
import com.intelligent.ispc.external.rcall.dto.ToleranceParamDto;
import com.intelligent.ispc.external.rcall.service.AnalysisService;
import com.intelligent.ispc.foundation.poi.SampleExcelBuilder;
import com.intelligent.ispc.utils.ExportFileStatus;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.task.TaskExecutor;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;

/**
 * Created by QiangChen on 2016/8/23.
 */
@Service
public class ToleranceServiceImpl extends BaseCacheServiceImpl implements ToleranceService {
    private static Logger logger = LoggerFactory.getLogger(ToleranceServiceImpl.class);

    @Autowired
    private ProjectService projectService;

    @Autowired
    private ToleranceItemDao toleranceItemDao;

    @Autowired
    private ToleranceSchemeDao toleranceSchemeDao;

    @Autowired
    private StatisticAnalysisParameterDao statisticAnalysisParameterDao;

    @Autowired
    private AnalysisService analysisService;

    @Autowired
    private TaskExecutor taskExecutor;

    @Autowired
    private SecurityService securityService;

    @Autowired
    private ExportFileService exportFileService;

    @Autowired
    private SimpMessagingTemplate msgTemplate;

    @Autowired
    private ProjectDao projectDao;

    @Override
    public List<ToleranceSchemeDto> findSchemeByProject(Long projectId) {
        if (projectId == null) {
            throw new ApplicationException(ExceptionMessages.EXCEPTION_PARAMETER_INPUT_INVALID);
        }

        Specification<ToleranceScheme> spec = (Root<ToleranceScheme> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
            Join<ToleranceScheme, Project> projectJoin = root.join(root.getModel().getSingularAttribute("project", Project.class), JoinType.LEFT);
            List<Predicate> predicates = Lists.newArrayList();
            Predicate p = cb.equal(projectJoin.get("id").as(Long.class), projectId);
            predicates.add(p);

            if (!predicates.isEmpty()) {
                query.where(cb.and(predicates.toArray(new Predicate[predicates.size()])));
            }
            return query.getRestriction();
        };

        List<ToleranceScheme> entityList = toleranceSchemeDao.findAll(spec, new Sort(Sort.Direction.ASC, "name"));
        logger.debug("Searching ToleranceScheme, total elements:{}", entityList.size());
        List<ToleranceSchemeDto> dtoList = Lists.newArrayList();

        for (ToleranceScheme entity : entityList) {
            ToleranceSchemeDto dto = new ToleranceSchemeDto();
            BeanMapper.copy(entity, dto);
            dtoList.add(dto);
        }

        return dtoList;
    }

    @Override
    public List<ToleranceItemDto> findItemByScheme(Long projectId, Long schemeId) {
        if (projectId == null || schemeId == null) {
            throw new ApplicationException(ExceptionMessages.EXCEPTION_PARAMETER_INPUT_INVALID);
        }

        Specification<ToleranceItem> spec = (Root<ToleranceItem> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
            Join<ToleranceItem, ToleranceScheme> toleranceSchemeJoin = root.join(root.getModel().getSingularAttribute("toleranceScheme", ToleranceScheme.class), JoinType.LEFT);
            Join projectJoin = toleranceSchemeJoin.join("project", JoinType.LEFT);
            List<Predicate> predicates = Lists.newArrayList();
            Predicate pScheme = cb.equal(toleranceSchemeJoin.get("id").as(Long.class), schemeId);
            Predicate pProject = cb.equal(projectJoin.get("id").as(Long.class), projectId);
            Predicate p = cb.and(pScheme, pProject);
            predicates.add(p);

            if (!predicates.isEmpty()) {
                query.where(cb.and(predicates.toArray(new Predicate[predicates.size()])));
            }
            return query.getRestriction();
        };

        List<ToleranceItem> entityList = toleranceItemDao.findAll(spec, new Sort(Sort.Direction.ASC, "code"));
        logger.debug("Searching ToleranceItem, total elements:{}", entityList.size());
        List<ToleranceItemDto> dtoList = Lists.newArrayList();

        for (ToleranceItem entity : entityList) {
            ToleranceItemDto dto = new ToleranceItemDto();
            BeanMapper.copy(entity, dto);
            dtoList.add(dto);
        }

        return dtoList;
    }

    @Override
    public List<ToleranceItemDto> findItemByScheme(Long schemeId) {
        if (schemeId == null) {
            throw new ApplicationException(ExceptionMessages.EXCEPTION_PARAMETER_INPUT_INVALID);
        }
        Specification<ToleranceItem> spec = (Root<ToleranceItem> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
            Join<ToleranceItem, ToleranceScheme> schemeJoin = root.join(root.getModel().getSingularAttribute("toleranceScheme", ToleranceScheme.class), JoinType.LEFT);
            List<Predicate> predicates = Lists.newArrayList();
            Predicate p = cb.equal(schemeJoin.get("id").as(Long.class), schemeId);
            predicates.add(p);

            if (!predicates.isEmpty()) {
                query.where(cb.and(predicates.toArray(new Predicate[predicates.size()])));
            }
            return query.getRestriction();
        };

        List<ToleranceItem> entityList = toleranceItemDao.findAll(spec, new Sort(Sort.Direction.ASC, "code"));
        logger.debug("Searching ToleranceItem, total elements:{}", entityList.size());
        List<ToleranceItemDto> dtoList = Lists.newArrayList();

        for (ToleranceItem entity : entityList) {
            ToleranceItemDto dto = new ToleranceItemDto();
            BeanMapper.copy(entity, dto);
            dtoList.add(dto);
        }

        return dtoList;
    }

    @Override
    public boolean isSchemeExistInProject(Long projectId, String schemeName) {
        if (StringUtils.isBlank(schemeName) || projectId == null) {
            throw new ApplicationException(ExceptionMessages.EXCEPTION_PARAMETER_INPUT_INVALID);
        }
        boolean isExist = false;
        logger.debug("Checking Scheme: {}, {}", projectId, schemeName);
        ToleranceScheme toleranceScheme = toleranceSchemeDao.findByNameAndProjectId(schemeName, projectId);
        if (toleranceScheme != null) {
            isExist = true;
        }

        return isExist;
    }

    @Override
    public void createScheme(ToleranceSchemeDto toleranceSchemeDto) {
        if (toleranceSchemeDto == null || toleranceSchemeDto.getProjectId() == null) {
            throw new ApplicationException(ExceptionMessages.EXCEPTION_PARAMETER_INPUT_INVALID);
        }

        ToleranceScheme toleranceScheme = new ToleranceScheme();
        ToleranceSchemeDto.dtoToEntity(toleranceSchemeDto, toleranceScheme);
        toleranceSchemeDao.save(toleranceScheme);
    }

    @Override
    public void importScheme(ToleranceSchemeDto toleranceSchemeDto, String filePath, ProcessEvent processEvent) {
        //TODO
        Long projectId = toleranceSchemeDto.getProjectId();

        taskExecutor.execute(new Thread() {
            public void run() {
                Workbook wb = null;
                double process = 50;
                long fileSizeOffset = 0;
                boolean isLastUpdate = true;

                File file = new File(filePath);
                if (!file.exists()) {
                    throw new ApplicationException(ExceptionMessages.EXCEPTION_OBJECT_DOES_NOT_EXIST);
                }
                long fileSize = file.length();

                if (projectId == null) {
                    throw new ApplicationException(ExceptionMessages.EXCEPTION_PARAMETER_INPUT_INVALID);
                }

                logger.debug("Checking project: {}", projectId);

                Project project = projectDao.findById(projectId);
                if (project == null) {
                    throw new ApplicationException(ExceptionMessages.EXCEPTION_OBJECT_DOES_NOT_EXIST);
                }

                ToleranceScheme toleranceScheme = new ToleranceScheme();

                toleranceScheme.setProject(project);
                toleranceScheme.setName(toleranceSchemeDto.getName());

                toleranceSchemeDao.save(toleranceScheme);

                try {
                    InputStream stream = new FileInputStream(filePath);
                    String fileType = filePath.substring(filePath.lastIndexOf('.') + 1);

                    if (fileType.equals("xlsx")) {
                        logger.debug("Reading xlsx file: {}", filePath);
                        wb = new XSSFWorkbook(stream);
                    } else if (fileType.equals("xls")) {
                        logger.debug("Reading xls file: {}", filePath);
                        wb = new HSSFWorkbook(stream);
                    } else {
                        throw new ApplicationException(ExceptionMessages.EXCEPTION_DATAIMPORT_FILE_TYPE_ERROR);
                    }

                    Sheet sheet1 = wb.getSheetAt(0);
                    Table<Long, Integer, String> itemNameTable = HashBasedTable.create();
                    Table<Long, String, String> dataRowTable = HashBasedTable.create();

                    for (Row row : sheet1) {
                        long currentRowNum = row.getRowNum();
                        int tdLength = row.getLastCellNum();
                        //head
                        if (currentRowNum < 1) {
                            long rowByteSize = 0;
                            for(int i = 0; i < tdLength; i++) {
                                if(StringUtils.isBlank(getCellValue(row.getCell(i)))) {
                                    continue;
                                }
                                itemNameTable.put(currentRowNum, i, getCellValue(row.getCell(i)));
                                rowByteSize += getCellValue(row.getCell(i)).getBytes().length;
                            }
                            fileSizeOffset += rowByteSize;
                            process += Math.round(rowByteSize / fileSize * 50);
                            processEvent.update(process, "importing...", fileSizeOffset, isLastUpdate);
                        } else {
                            //real data
                            dataRowTable.row(0L).clear();
                            long rowByteSize = 0;
                            logger.debug("Current Line: ", currentRowNum);

                            for (int i = 0; i < tdLength; i++) {
                                Cell cell = row.getCell(i);
                                rowByteSize += getCellValue(cell) == null ? 0 : getCellValue(cell).getBytes().length;
                                dataRowTable.put(0L, itemNameTable.row(0L).get(i), getCellValue(cell) == null ? "" : getCellValue(cell));
                            }
                            if(rowByteSize == 0) {
                                continue;
                            }
                            fileSizeOffset += rowByteSize;
                            process += Math.round(rowByteSize / fileSize * 50);

                            ToleranceItem toleranceItem = new ToleranceItem();
                            toleranceItem.setToleranceScheme(toleranceSchemeDao.findByNameAndProjectId(toleranceSchemeDto.getName(), projectId));

                            String code = dataRowTable.row(0L).get("Label").toString();
                            toleranceItem.setCode(code);

                            String componentName = dataRowTable.row(0L).get("Component Name").toString();
                            toleranceItem.setComponentName(componentName);

                            String loopType = dataRowTable.row(0L).get("Chain Type").toString();
                            toleranceItem.setLoopType(loopType);

                            String coefficient = dataRowTable.row(0L).get("Transfer Coefficient").toString();
                            toleranceItem.setCoefficient(coefficient);

                            String nominalSize = dataRowTable.row(0L).get("Nominal(mm)").toString();
                            toleranceItem.setNominalSize(nominalSize);

                            String unilateralTolerance = dataRowTable.row(0L).get("Tolerance").toString();
                            toleranceItem.setUnilateralTolerance(unilateralTolerance);

                            String ldl = dataRowTable.row(0L).get("Minimum(mm)").toString();
                            toleranceItem.setLdl(ldl);

                            String udl = dataRowTable.row(0L).get("Maximum(mm)").toString();
                            toleranceItem.setUdl(udl);

                            String mean = dataRowTable.row(0L).get("Mean(mm)").toString();
                            toleranceItem.setMean(mean);

                            String sigma = dataRowTable.row(0L).get("Distribution").toString();
                            toleranceItem.setSigma(sigma);

                            toleranceItemDao.save(toleranceItem);
                        }
                    }
                    processEvent.update(100, "Finished.", fileSizeOffset, isLastUpdate);
                    stream.close();
                    wb.close();
                } catch (Exception e) {
                    throw new ApplicationException(e);
                } finally {
                    if (wb != null) {
                        try {
                            wb.close();
                        } catch (IOException e) {
                            throw new ApplicationException(e);
                        }
                    }
                    processEvent.update(100, "successfully import data", fileSizeOffset, isLastUpdate);
//                    if (file.exists()) {
//                        file.delete();
//                    }
                }
            }
        });
    }

    private String getCellValue (Cell cell) {
        String cellValue = null;
        if (cell == null) {
            return cellValue;
        }

        int cellType = cell.getCellType();
        switch(cellType) {
            case Cell.CELL_TYPE_STRING:
                cellValue = cell.getStringCellValue();
                break;
            case Cell.CELL_TYPE_NUMERIC:
                if(DateUtil.isCellDateFormatted(cell)) {
                    cellValue = cell.getDateCellValue().toString();
                }
                else {
                    cellValue = String.valueOf(cell.getNumericCellValue());
                }
                break;
            case Cell.CELL_TYPE_BOOLEAN:
                cellValue = String.valueOf(cell.getBooleanCellValue());
                break;
            case Cell.CELL_TYPE_BLANK:
                cellValue = cell.getStringCellValue();
                break;
            case Cell.CELL_TYPE_ERROR:
                cellValue = null;
                break;
            case Cell.CELL_TYPE_FORMULA:
                try {
                    cellValue = String.valueOf(cell.getNumericCellValue());
                } catch(Exception e) {
                    cellValue = null;
                }
                break;
            default:
                cellValue = null;
        }
        return  cellValue;
    }


    @Override
    public void deleteScheme(Long id) {
        if (id == null) {
            throw new ApplicationException(ExceptionMessages.EXCEPTION_PARAMETER_INPUT_INVALID);
        }
        ToleranceScheme toleranceScheme = toleranceSchemeDao.findById(id);
        if (toleranceScheme == null) {
            throw new ApplicationException(ExceptionMessages.EXCEPTION_OBJECT_DOES_NOT_EXIST);
        }

        List<ToleranceItem> items = toleranceScheme.getItems();
        if (items != null && !items.isEmpty()) {
            toleranceScheme.getItems().clear();
        }

        toleranceSchemeDao.delete(toleranceScheme);
    }

    @Override
    public void createItem(ToleranceItemDto toleranceItemDto) {
        if (toleranceItemDto == null || toleranceItemDto.getProjectId() == null || toleranceItemDto.getSchemeId() == null) {
            throw new ApplicationException(ExceptionMessages.EXCEPTION_PARAMETER_INPUT_INVALID);
        }

        ToleranceItem toleranceItem = new ToleranceItem();
        ToleranceItemDto.dtoToEntity(toleranceItemDto, toleranceItem);
        toleranceItemDao.save(toleranceItem);
    }

    @Override
    public void updateItem(ToleranceItemDto toleranceItemDto) {
        if (toleranceItemDto == null || toleranceItemDto.getId() == null) {
            throw new ApplicationException(ExceptionMessages.EXCEPTION_PARAMETER_INPUT_INVALID);
        }

        ToleranceItem toleranceItem = toleranceItemDao.findOne(toleranceItemDto.getId());
        BeanMapper.copy(toleranceItemDto, toleranceItem);
        toleranceItemDao.save(toleranceItem);
    }

    @Override
    public void deleteItem(Long id) {
        if (id == null) {
            throw new ApplicationException(ExceptionMessages.EXCEPTION_PARAMETER_INPUT_INVALID);
        }

        ToleranceItem toleranceItem = toleranceItemDao.findById(id);
        if (toleranceItem == null) {
            throw new ApplicationException(ExceptionMessages.EXCEPTION_OBJECT_DOES_NOT_EXIST);
        }

        toleranceItemDao.delete(toleranceItem);
    }

    @Override
    public ToleranceResultDto analysis(ToleranceSearchConditionDto conditionDto) {
        if (conditionDto.getProjectId() == null || conditionDto.getSchemeId() == null || conditionDto.getLsl() == null || conditionDto.getUsl() == null || conditionDto.getCalculateTimes() == null) {
            throw new ApplicationException(ExceptionMessages.EXCEPTION_PARAMETER_INPUT_INVALID);
        }

        ToleranceScheme toleranceScheme = toleranceSchemeDao.findById(conditionDto.getSchemeId());
        toleranceScheme.setLsl(conditionDto.getLsl());
        toleranceScheme.setUsl(conditionDto.getUsl());
        toleranceScheme.setCalculateTimes(conditionDto.getCalculateTimes());
        toleranceSchemeDao.save(toleranceScheme);

        ToleranceParamDto toleranceParamDto = new ToleranceParamDto();
        toleranceParamDto.setUsl(conditionDto.getUsl());
        toleranceParamDto.setLsl(conditionDto.getLsl());
        Integer group = projectService.findStatisticAnalysisParameterByProjectId(conditionDto.getProjectId().toString()).get(0).getDistributionChartGroupingNumber();
        if (group == null) {
            group = (int) Math.ceil(Math.sqrt(conditionDto.getCalculateTimes().intValue()));
        }
        toleranceParamDto.setGroup(group);
        List<ToleranceItemDto> toleranceItem = findItemByScheme(conditionDto.getSchemeId());
        toleranceParamDto.setAnalysisData(toleranceItem);
        toleranceParamDto.setCalculateTimes(conditionDto.getCalculateTimes());

        return analysisService.analyseToleranceChartData(toleranceParamDto);
    }

    @Override
    public void export(ToleranceSearchConditionDto conditionDto) {
        if (conditionDto.getProjectId() == null || conditionDto.getSchemeId() == null) {
            throw new ApplicationException(ExceptionMessages.EXCEPTION_PARAMETER_INPUT_INVALID);
        }

        logger.debug("Find scheme by Id : {} " + conditionDto.getSchemeId());
        ToleranceScheme scheme = toleranceSchemeDao.findById(conditionDto.getSchemeId());
        if (scheme == null) {
            throw new ApplicationException(ExceptionMessages.EXCEPTION_OBJECT_DOES_NOT_EXIST);
        }
        scheme.setLsl(conditionDto.getLsl());
        scheme.setUsl(conditionDto.getUsl());
        scheme.setCalculateTimes(conditionDto.getCalculateTimes());
        toleranceSchemeDao.save(scheme);

        ToleranceSchemeDto toleranceSchemeDto = new ToleranceSchemeDto();
        BeanMapper.copy(scheme, toleranceSchemeDto);

        logger.debug("Find done, scheme = {} " + scheme.getName());

        String loginName = securityService.getCurrentUserLoginName();
        Long userId = securityService.getCurrentUser().getId();

        taskExecutor.execute(new Thread() {
            public void run() {
                String projectName = projectService.findById(conditionDto.getProjectId().toString()).getName();
                String schemeName = scheme.getName();
                DateTimeFormatter format = DateTimeFormat.forPattern("yyyyMMddHHmmss");
                DateTime now = new DateTime();
                String fix = now.toString(format);
                StringBuilder sb1 = new StringBuilder();
                sb1.append("export_").append(projectName).append("_")
                        .append(loginName).append("_").append(schemeName).append("_").append(fix).append(".").append("jpg");
                String imgPath = ApplicationUtil.getProjectPathWithSeparator() + "exports/temp/";
                File file1 = new File(imgPath);
                if (!file1.exists() && !file1.isDirectory()) {
                    file1.mkdir();
                }
                imgPath += sb1.toString();
                logger.debug("Export tolerance result img to file : {} " + imgPath);

                StringBuilder sb2 = new StringBuilder();
                sb2.append("export_").append(projectName).append("_").append(schemeName)
                        .append("_").append(fix).append(".").append("xlsx");
                String fileName = sb2.toString();
                String savePath = ApplicationUtil.getProjectPathWithSeparator() + "exports" + ApplicationUtil.getFileSeparator();
                File file2 = new File(savePath);
                if (!file2.exists() && !file2.isDirectory()) {
                    file2.mkdir();
                }
                String filePath = savePath + fileName;

                ExportFileDto exportFileDto = new ExportFileDto();
                exportFileDto.setCreateBy(loginName);
                exportFileDto.setCreateTime(now.toDate());
                exportFileDto.setProjectName(projectName);
                exportFileDto.setStatus(ExportFileStatus.EXPORTING.toString());
                exportFileDto.setDataType("Tolerance");
                exportFileDto.setUrl("exportsfile/" + fileName);
                Long fileId = exportFileService.createExportFile(exportFileDto);

                logger.debug("Export tolerance result to file : {} " + filePath);

                Integer calculateTimes = conditionDto.getCalculateTimes() == null ? toleranceSchemeDto.getCalculateTimes() : conditionDto.getCalculateTimes();
                Integer group = projectService.findStatisticAnalysisParameterByProjectId(conditionDto.getProjectId().toString()).get(0).getDistributionChartGroupingNumber();
                if (group == null) group = (int) Math.ceil(Math.sqrt(calculateTimes.intValue()));
                Double lsl = conditionDto.getLsl();
                Double usl = conditionDto.getUsl();
                String title = toleranceSchemeDto.getName();
                List<ToleranceItemDto> toleranceItemDtos = findItemByScheme(conditionDto.getSchemeId());

                ToleranceParamDto paramDto = new ToleranceParamDto();
                paramDto.setUsl(usl);
                paramDto.setLsl(lsl);
                paramDto.setAnalysisData(toleranceItemDtos);
                paramDto.setCalculateTimes(calculateTimes);
                paramDto.setImgPath(imgPath);
                paramDto.setTitle(title);
                paramDto.setGroup(group);

                ToleranceResultDto resultDto = analysisService.analyseToleranceChartPlot(paramDto);
                if (resultDto == null) {
                    logger.error("export tolerance result failed! Calculation result Invalid");
                    msgTemplate.setUserDestinationPrefix("/data/");
                    msgTemplate.convertAndSend("/topic/data/exportDownloadListener#" + userId, "{'result':'error','url':'" + exportFileDto.getUrl() + "'}");
                    exportFileService.updateExportFileStatus(fileId, ExportFileStatus.FAILED);
                    throw new ApplicationException(ExceptionMessages.EXCEPTION_PARAMETER_INPUT_INVALID);
                } else {
                    try {
                        TolExportCellFactory factory = new TolExportCellFactory();
                        factory.buildTolerance4SingleItem(paramDto, resultDto);
                        TolExcelBuilder tolExcelBuilder = new TolExcelBuilder();
                        tolExcelBuilder.drawExcel(filePath, factory);

                        exportFileService.updateExportFileStatus(fileId, ExportFileStatus.FINISHED);
                    } catch (Exception e) {
                        logger.error("export tolerance result failed! ", e);
                        exportFileService.updateExportFileStatus(fileId, ExportFileStatus.FAILED);
                        msgTemplate.setUserDestinationPrefix("/data/");
                        msgTemplate.convertAndSend("/topic/data/exportDownloadListener#" + userId, "{'result':'error','url':'" + exportFileDto.getUrl() + "'}");
                    }

                    msgTemplate.setUserDestinationPrefix("/data/");
                    msgTemplate.convertAndSend("/topic/data/exportDownloadListener#" + userId, "{'result':'success','url':'" + exportFileDto.getUrl() + "'}");
                }
            }
        });
    }



    /*
    write setXxx for Mock test
     */
    public void setToleranceSchemeDao(ToleranceSchemeDao toleranceSchemeDao) {
        this.toleranceSchemeDao = toleranceSchemeDao;
    }

    public void setToleranceItemDao(ToleranceItemDao toleranceItemDao) {
        this.toleranceItemDao = toleranceItemDao;
    }

    public void setProjectService(ProjectService projectService) {
        this.projectService = projectService;
    }

}